package com.ys.malini.util;

import java.math.BigDecimal;
import java.text.DecimalFormat;

import org.apache.commons.validator.GenericValidator;

public class MathUtils {

	private static final int DEF_DIV_SCALE = 10;
	public static String AMOUNT_FORMAT = "#0.00";
	public static String NUM_FORMAT="#0";

	/**
	 * 两个Double数相加
	 * 
	 * @param v1
	 * @param v2
	 * @return Double
	 */
	public static Double add(Double v1, Double v2) {
		BigDecimal b1 = new BigDecimal(v1.toString());
		BigDecimal b2 = new BigDecimal(v2.toString());
		return b1.add(b2).doubleValue();
	}

	/**
	 * 两个Double数相减
	 * 
	 * @param v1
	 * @param v2
	 * @return Double
	 */
	public static Double sub(Double v1, Double v2) {
		BigDecimal b1 = new BigDecimal(v1.toString());
		BigDecimal b2 = new BigDecimal(v2.toString());
		return b1.subtract(b2).doubleValue();
	}

	/**
	 * 两个Double数相乘
	 * 
	 * @param v1
	 * @param v2
	 * @return Double
	 */
	public static Double mul(Double v1, Double v2) {
		BigDecimal b1 = new BigDecimal(v1.toString());
		BigDecimal b2 = new BigDecimal(v2.toString());
		return b1.multiply(b2).doubleValue();
	}

	/**
	 * 两个Double数相除
	 * 
	 * @param v1
	 * @param v2
	 * @return Double
	 */
	public static Double div(Double v1, Double v2) {
		BigDecimal b1 = new BigDecimal(v1.toString());
		BigDecimal b2 = new BigDecimal(v2.toString());
		return b1.divide(b2, DEF_DIV_SCALE, BigDecimal.ROUND_HALF_UP)
				.doubleValue();
	}

	/**
	 * 两个Double数相除，并保留scale位小数
	 * 
	 * @param v1
	 * @param v2
	 * @param scale
	 * @return Double
	 */
	public static Double div(Double v1, Double v2, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException(
					"The scale must be a positive integer or zero");
		}
		BigDecimal b1 = new BigDecimal(v1.toString());
		BigDecimal b2 = new BigDecimal(v2.toString());
		return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
	}

	public static void main(String[] args) {
		System.out.println("=============== " + 199 * 0.1 / 100d);
		System.out.println(GenericValidator.matchRegexp(
				"123456sdsdfds7890123456789011", "\\w"));
		System.out.println();

	}

	/**
	 * format "#0.00"
	 * 
	 * @param format
	 * @param num
	 * @return
	 */
	public static String format(String format, Double num) {
		DecimalFormat df = new DecimalFormat(format);
		return df.format(num);
	}
	
	public static String format(String format, Long num) {
		DecimalFormat df = new DecimalFormat(format);
		return df.format(num);
	}

	public static String format2Amount(Double num) {
		DecimalFormat df = new DecimalFormat(AMOUNT_FORMAT);
		return df.format(num);
	}

	/**
	 * format "#0.00"
	 * 
	 * @param format
	 * @param num
	 * @return
	 */
	public static String format(String format, String num) {
		DecimalFormat df = new DecimalFormat(format);
		return df.format(num);
	}

	public static String format2Amount(String num) {
		DecimalFormat df = new DecimalFormat(AMOUNT_FORMAT);
		return df.format(num);
	}

	/**
	 * 根据金额和比率计算积分<br>
	 * 如果amount和rate 任何一个为null，则返回null
	 * 
	 * @param amount
	 * @param rate
	 * @return 如果计算结果为null，则返回0
	 */
	public static Long getPoint(Double amount, Double rate) {
		if (amount == null || rate == null) {
			return null;
		}
		Long point = div(amount * 100, rate).longValue();
		return point;
	}

	/**
	 * 根据积分和比率计算金额<br>
	 * 如果points和rate 任何一个为null，则返回null
	 * 
	 * @param points
	 * @param rate
	 * @return 如果计算结果为null，则返回0
	 */
	public static Double getAmount(Long points, Double rate) {
		if (points == null || rate == null) {
			return null;
		}
		Double amount = div(points * rate, 100d).doubleValue();
		return amount;
	}

	/**
	 * 根据金额的分（不是积分的概念），转换成标准的金额形式。<br>
	 * 1001分---> 10.01元
	 * 
	 * @param amount
	 * @return
	 */
	public static Double getAmount(Long amount) {
		return div(amount.doubleValue(), 100d);
	}

	/**
	 * 根据金额的分（不是积分的概念），转换成标准的金额形式。<br>
	 * 1001分---> 10.01元
	 * 
	 * @param amount
	 * @return
	 */
	public static Double getAmount(String amount) {
		return div(Double.parseDouble(amount), 100d);
	}

	/**
	 * 根据金额计算金额分
	 * 
	 * @param amount
	 * @return
	 */
	public static Long getAmountPoint(Double amount) {
		return mul(amount, 100d).longValue();
	}

	/**
	 * 根据金额计算金额分
	 * 
	 * @param amount
	 * @return
	 */
	public static Long getAmountPoint(String amount) {
		return mul(Double.parseDouble(amount), 100d).longValue();
	}

}
